#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
基于事件系统的插件管理器
"""

import asyncio
import json
import os
import importlib.util
from typing import Dict, List, Optional, Any, Callable
from pathlib import Path

from common.logger import logger
from database.messsagDB import Message
from plugins.event_system import EventBus, Event, EventType


class PluginManager:
    """基于事件系统的插件管理器"""
    
    def __init__(self):
        self.plugins_dir = "plugins"
        self.plugins: Dict[str, Any] = {}
        self.event_bus = EventBus()
        
    async def load_plugins(self):
        """加载所有插件"""
        try:
            logger.info("开始加载插件...")
            
            # 遍历插件目录
            plugins_path = Path(self.plugins_dir)
            if not plugins_path.exists():
                logger.warning(f"插件目录不存在: {self.plugins_dir}")
                return
            
            # 查找所有插件目录
            for plugin_dir in plugins_path.iterdir():
                if plugin_dir.is_dir() and not plugin_dir.name.startswith('_'):
                    await self._load_plugin(plugin_dir)
            
            logger.info(f"插件加载完成，共加载 {len(self.plugins)} 个插件")
            
        except Exception as e:
            logger.error(f"加载插件失败: {e}")
    
    async def _load_plugin(self, plugin_dir: Path):
        """加载单个插件"""
        try:
            plugin_name = plugin_dir.name
            logger.info(f"正在加载插件: {plugin_name}")
            
            # 检查插件配置文件
            config_file = plugin_dir / "config.json"
            if not config_file.exists():
                logger.warning(f"插件 {plugin_name} 缺少配置文件")
                return
            
            # 读取插件配置
            with open(config_file, "r", encoding="utf-8") as f:
                config = json.load(f)
            
            # 检查插件是否启用
            if not config.get("enabled", True):
                logger.info(f"插件 {plugin_name} 已禁用，跳过加载")
                return
            
            # 检查插件主文件
            main_file = plugin_dir / "main.py"
            if not main_file.exists():
                logger.warning(f"插件 {plugin_name} 缺少主文件 main.py")
                return
            
            # 设置Python路径，确保插件能找到相关模块
            import sys
            project_root = Path(__file__).parent.parent
            if str(project_root) not in sys.path:
                sys.path.insert(0, str(project_root))
            
            # 动态加载插件模块
            spec = importlib.util.spec_from_file_location(
                f"plugins.{plugin_name}.main",
                main_file
            )
            module = importlib.util.module_from_spec(spec)
            
            # 设置模块的__file__属性
            module.__file__ = str(main_file)
            
            spec.loader.exec_module(module)
            
            # 检查插件类
            if not hasattr(module, 'Plugin'):
                logger.warning(f"插件 {plugin_name} 缺少 Plugin 类")
                return
            
            # 实例化插件
            plugin_instance = module.Plugin(config, self.event_bus)
            
            # 调用插件的on_load方法
            if hasattr(plugin_instance, 'on_load'):
                await plugin_instance.on_load()
            
            # 注册插件
            self.plugins[plugin_name] = {
                "instance": plugin_instance,
                "config": config,
                "module": module,
                "path": plugin_dir
            }
            
            logger.info(f"插件 {plugin_name} 加载成功")
            
        except Exception as e:
            logger.error(f"加载插件 {plugin_dir.name} 失败: {e}")
            import traceback
            logger.error(traceback.format_exc())
    
    async def process_message(self, msg:Message, msg_api: Any) -> Optional[Dict[str, Any]]:
        """通过事件系统处理消息"""
        try:
            # 创建事件数据

            # 根据消息类型创建事件
            event_type = self._get_event_type(msg.msg_type)
            event = Event(event_type, msg)
            
            # 发送事件
            response = await self.event_bus.emit(event)
            
            return response
            
        except Exception as e:
            logger.error(f"处理消息失败: {e}")
            return None
    
    def _get_event_type(self, msg_type: int) -> EventType:
        """根据消息类型获取事件类型"""
        event_type_map = {
            1: EventType.MESSAGE_TEXT,
            3: EventType.MESSAGE_IMAGE,
            34: EventType.MESSAGE_VOICE,
            43: EventType.MESSAGE_VIDEO,
            47: EventType.MESSAGE_EMOJI,
            49: EventType.MESSAGE_MULTIMEDIA
        }
        return event_type_map.get(msg_type, EventType.MESSAGE_ANY)
    
    def get_plugin_info(self) -> Dict[str, Any]:
        """获取插件信息"""
        info = {}
        for name, plugin_data in self.plugins.items():
            plugin_instance = plugin_data["instance"]
            info[name] = {
                "config": plugin_data["config"],
                "enabled": plugin_instance.is_enabled() if hasattr(plugin_instance, 'is_enabled') else True,
                "info": plugin_instance.get_info() if hasattr(plugin_instance, 'get_info') else {}
            }
        return info
    
    def get_event_listeners_info(self) -> Dict[str, Any]:
        """获取事件监听器信息"""
        info = {}
        for event_type in EventType:
            count = self.event_bus.get_listener_count(event_type)
            if count > 0:
                info[event_type.name] = count
        return info
    
    async def reload_plugin(self, plugin_name: str) -> bool:
        """重新加载插件"""
        try:
            logger.info(f"重新加载插件: {plugin_name}")
            
            # 卸载旧插件
            await self.unload_plugin(plugin_name)
            
            # 重新加载
            plugin_dir = Path(self.plugins_dir) / plugin_name
            if plugin_dir.exists():
                await self._load_plugin(plugin_dir)
                return True
            else:
                logger.error(f"插件目录不存在: {plugin_name}")
                return False
                
        except Exception as e:
            logger.error(f"重新加载插件 {plugin_name} 失败: {e}")
            return False
    
    async def unload_plugin(self, plugin_name: str) -> bool:
        """卸载插件"""
        try:
            if plugin_name in self.plugins:
                plugin_data = self.plugins[plugin_name]
                plugin_instance = plugin_data["instance"]
                
                # 调用插件的on_unload方法
                if hasattr(plugin_instance, 'on_unload'):
                    await plugin_instance.on_unload()
                
                # 插件卸载时会自动清理事件监听器
                del self.plugins[plugin_name]
                logger.info(f"插件 {plugin_name} 已卸载")
                return True
            else:
                logger.warning(f"插件 {plugin_name} 不存在")
                return False
        except Exception as e:
            logger.error(f"卸载插件 {plugin_name} 失败: {e}")
            return False
    
    def enable_plugin(self, plugin_name: str) -> bool:
        """启用插件"""
        try:
            if plugin_name in self.plugins:
                plugin_instance = self.plugins[plugin_name]["instance"]
                if hasattr(plugin_instance, 'enable'):
                    plugin_instance.enable()
                    return True
            return False
        except Exception as e:
            logger.error(f"启用插件 {plugin_name} 失败: {e}")
            return False
    
    def disable_plugin(self, plugin_name: str) -> bool:
        """禁用插件"""
        try:
            if plugin_name in self.plugins:
                plugin_instance = self.plugins[plugin_name]["instance"]
                if hasattr(plugin_instance, 'disable'):
                    plugin_instance.disable()
                    return True
            return False
        except Exception as e:
            logger.error(f"禁用插件 {plugin_name} 失败: {e}")
            return False
    
    def add_event_listener(self, event_type: EventType, handler: Callable, async_handler: bool = True):
        """添加事件监听器"""
        self.event_bus.add_listener(event_type, handler, async_handler)
    
    def remove_event_listener(self, event_type: EventType, handler: Callable):
        """移除事件监听器"""
        self.event_bus.remove_listener(event_type, handler)
    
    def add_middleware(self, middleware: Callable):
        """添加中间件"""
        self.event_bus.add_middleware(middleware)
    
    def clear_event_listeners(self, event_type: Optional[EventType] = None):
        """清除事件监听器"""
        self.event_bus.clear_listeners(event_type) 